package cn.mugutu.webrtc.websocket.util;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import cn.mugutu.webrtc.utils.JsonUtil;
import cn.mugutu.webrtc.utils.PrintUtil;
import cn.mugutu.webrtc.websocket.domain.SessionVo;
import cn.mugutu.webrtc.websocket.result.BaseMsg;

import com.alibaba.fastjson.JSON;
/**
 * websocket链接通话处理工具类
 * @author gan
 *
 */
public class WebSocketUtil {
	
	//保存报警人和接警员通话session关系
	public static final Map<String,String> police_user = Collections.synchronizedMap(new HashMap<String, String>());
	//存放在线接警员(sessionId,session)
	public static final Map<String,SessionVo> police_sessions = Collections.synchronizedMap(new HashMap<String,SessionVo>());
	//存放在线的报警人(sessionId,session)
	public static final Map<String,SessionVo> user_sessions = Collections.synchronizedMap(new HashMap<String,SessionVo>());
	
	/**
	 * 新连接一个报警用户或者警方处理员
	 * 链接的时候传入的参数:
	 * type=user(报警人方)
	 * type=police(接入的警方)
	 * @param session
	 */
	public static void addUser(WebSocketSession session){
		String type = session.getAttributes().get("type").toString();
		String uid  = session.getAttributes().get("uid").toString();
		String toId = session.getAttributes().get("toId").toString();
		
		//保存通话关联关系
		police_user.put(uid, toId);
		
		SessionVo sessionVo = new SessionVo(uid, session);
		if("user".equals(type)){
			user_sessions.put(session.getId(),sessionVo);
			PrintUtil.print("报警人:"+uid+"链接到websoket语音服务器. type:"+type+" uid:"+uid+" toId:"+toId);
		}else if("police".equals(type)){
			police_sessions.put(session.getId(), sessionVo);
			PrintUtil.print("接警员:"+uid+"链接到websoket语音服务器. type:"+type+" uid:"+uid+" toId:"+toId);
			
			//判断如果是接警员连接上了webrtc服务器就通知接警员连接成功,可以去通知报警人再连接webrtc服务器了
			BaseMsg baseMsg = new BaseMsg(true,"接警人:"+uid+"已经成功连接webrtc服务器.");
			try {
				session.sendMessage(new TextMessage(JsonUtil.ObjectToJSONString(baseMsg)));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	//移除一个在线用户或者是警员(断开一次通话要操作的是移除通话的接警员或者报警人,并且移除他们的通话关系)
	public static void removeUser(WebSocketSession session) {
		try {
			
		String sessionId = session.getId();
		String police_id = "";
		String user_id = "";
		boolean firstBreak = true; // 记录是谁先断开了通话,接警人先断开为true,报警人先断开为false
		if (police_sessions.get(sessionId) != null) { // 先断如果开通话的是警员
			SessionVo sessionVo = police_sessions.get(sessionId);
			if (sessionVo != null) {
				police_id = sessionVo.getIdentification();
				user_id = police_user.get(police_id);
			}
		} else { // 先断如果开通话的是报警人
			SessionVo sessionVo = user_sessions.get(sessionId);
			if (sessionVo != null) {
				user_id = sessionVo.getIdentification();
				police_id = police_user.get(user_id);
				firstBreak = false;
			}
		}

		police_sessions.remove(sessionId);
		user_sessions.remove(sessionId);
		// 移除通话关系
		police_user.remove(police_id);
		police_user.remove(user_id);

		if (firstBreak) {
			PrintUtil.print("接警员: " + police_id + " 先结束了本次报警通话...");
		} else {
			PrintUtil.print("报警人: " + user_id + " 先结束了本次报警通话...");
		}
		} catch (Exception e) {
			System.out.println("===============异常了。。。。");
			e.printStackTrace();
		}
	}
	
	
	
	//给所有在线用户发送广播消息
	public static void sendMessageToUsers(TextMessage message) {
		Map<String, SessionVo> allSession = new HashMap<String, SessionVo>();
		allSession.putAll(police_sessions);
		allSession.putAll(user_sessions);
		Set<String> keys = allSession.keySet();
		for (String key : keys) {
			WebSocketSession session = allSession.get(key).getSession();
			try {
				if (session.isOpen()) {
					session.sendMessage(message);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
    
    /**
     * 根据当前session获取与之通话的对方session
     * @param fromSession  当前会话session
     * @return 与之会话的session
     */
    public static WebSocketSession getToSessionByFromSession(WebSocketSession fromSession){
      	Map<String,SessionVo> allSession = new HashMap<String,SessionVo>();
		allSession.putAll(police_sessions);
		allSession.putAll(user_sessions);
    	Set<String> keys = allSession.keySet();
    	for (String key : keys) {
			SessionVo sessionVo = allSession.get(key);
			WebSocketSession tempSession = sessionVo.getSession();
			if(fromSession.getId().equals(tempSession.getId())){  //找到缓存的当前会话SessionVo
				//获取当前session对应人员的id
				String currentSessionId = sessionVo.getIdentification();
				//获取通话对方人员id
				String connectionSessionId = police_user.get(currentSessionId);
				//获取对方通话的session
				Set<String> keys2 = allSession.keySet();
				for (String key2 : keys2) {
					String identificationId = allSession.get(key2).getIdentification();
					if(identificationId.equals(connectionSessionId)){
						//返回对方通话的session
						return allSession.get(key2).getSession();
					}
				}
			}
		}
    	return null;
    }
    
    /**
     * 给通话对方发送消息
     * @param 发送方人员认证Id
     * @param message 要发送的消息
     * @param fromSession 发送方的session
     * @param policeIdOrUserId 发送方的认证id(policeId/userId)
     * @throws InterruptedException
     */
    public static void sendMessageToConnectionUser(WebSocketSession fromSession,TextMessage message) throws InterruptedException{
    	//获取通话对方的认证Id
    	WebSocketSession toSession = getToSessionByFromSession(fromSession);
    	
    	if(toSession==null){
    		//获取不到对方通话的链接,就每一秒去查询一次,查询5次/5s后返回超时信息
    		for(int i=0;i<5;i++){
    			Thread.sleep(1*1000); 
    			toSession = getToSessionByFromSession(fromSession);
    			if(toSession!=null) break;
    		}
    		
    		//没有获取到通话id,返回超时信息
    		if(toSession==null){
    			try {
//    				ParamsCommand paramsCommand = new ParamsCommand("connection_timeout",false,"链接超过5s,接警员繁忙,暂时无人接听.");
    				BaseMsg baseMsg = new BaseMsg(false, "链接超过5s,接警员繁忙,暂时无人接听.");
					fromSession.sendMessage(new TextMessage(JSON.toJSONString(baseMsg)));
				} catch (IOException e) {
					PrintUtil.print("5s内没有找到对方通话Session,链接通话超时..");
					e.printStackTrace();
				}
    			return;
    		}
    	}
    	
		//获取对方websocket会话session
    	try {
    		if(toSession!=null && toSession.isOpen()){
    			toSession.sendMessage(message);
        	}
		} catch (Exception e) {
			e.printStackTrace();
		}
     }
}
